package com.lzy.cloud.ticket.train.util;

import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;

/**
 * RSA加密解密工具类
 *
 * @author zhangzongshuang
 * @date 2015年5月8日 上午11:39:23
 */
public class RSAUtils {
    private static final String DEFAULT_CHARACTER = "UTF-8";
    /** RSA最大加密明文大小 */
    private static final int MAX_ENCRYPT_BLOCK = 117;
    /** RSA公钥密匙 */
    public static final String pubKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOXlyGsziLLK1vSwRIsEglSlSDEAIouYgD/qMlEy8cPf30FaBBuKzLUj7UqpzGfojucr9XSLPv+cEZSwSlqVZKECAwEAAQ==";

    /**
     * 使用公钥加密
     * @param key 公钥
     * @param content 明文
     * @return String 密文
     * @throws Exception
     */
    public static String encryptByPub(String key, String content) throws Exception {
        PublicKey pubKey = getPublicKey(key);
        byte[] data = encrypt(pubKey, content.getBytes(DEFAULT_CHARACTER));
        return Base64.encodeBase64String(data);
    }


    /**
     * 得到公钥
     * @param key 密钥字符串（经过base64编码）
     * @throws Exception
     */
    private static PublicKey getPublicKey(String key) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    /**
     * 加密
     * @param key 加密的密钥/公钥
     * @param data 明文数据
     * @return 密文数据
     * @throws Exception
     */
    private static byte[] encrypt(Key key, byte[] data) throws Exception {
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            int inputLen = data.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] cache;
            // 对数据分段加密
            for (int offSet = 0;  offSet<inputLen; offSet += MAX_ENCRYPT_BLOCK) {
                if (inputLen - offSet > 117) {
                    cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(data, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
            }
            byte[] encryptBytes = out.toByteArray();
            out.close();
            return encryptBytes;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    public static void main(String[] args) throws Exception {
        String contentName = "WR897550438";
        String contentPwd = "WR119";
        String encryptByPub = encryptByPub(pubKey, contentName);
        String encryptByPub1 = encryptByPub(pubKey, contentPwd);
        System.out.println(encryptByPub + "公钥加密密文：" + encryptByPub1);
    }
}
